package com.example.demo.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.common.entity.pojo.BaseEntityPoJo;
import com.example.demo.common.service.BaseService;
import com.example.demo.utils.SnowflakeIdWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * BaseServiceImpl.
 *
 * @author Mei Ruoxiao
 * @since 2020/9/3
 */
@SuppressWarnings("unchecked")
public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntityPoJo> extends ServiceImpl<M, T> implements BaseService<T> {

    Logger log = LoggerFactory.getLogger(BaseService.class);

    @Override
    public T create(T t) throws RuntimeException {
        t.setId(SnowflakeIdWorker.getId());
        t.setIsDelete(false);
        log.info("create:新增数据[{}]", t);
        this.getBaseMapper().insert(t);
        return t;
    }

    @Override
    public List<T> createBatch(List<T> ts) throws RuntimeException {
        if (CollectionUtils.isEmpty(ts)) {
            return Collections.emptyList();
        } else {
            String sqlStatement = this.sqlStatement(SqlMethod.INSERT_ONE);
            int size = ts.size();
            this.executeBatch((sqlSession) -> {
                AtomicInteger i = new AtomicInteger(1);
                ts.forEach((t) -> {
                    t.setId(SnowflakeIdWorker.getId());
                    t.setIsDelete(false);
//                    t.setCreateTime(new Date());
                    sqlSession.insert(sqlStatement, t);
                    if (i.get() % 50 == 0 || i.get() == size) {
                        sqlSession.flushStatements();
                    }
                    i.getAndIncrement();
                });
            });
            return ts;
        }
    }

    /**
     * @name lzy
     */
    @Override
    public List<T> createBatch(List<T> ts,Long companyId){
        if (CollectionUtils.isEmpty(ts)) {
            return Collections.emptyList();
        } else {
            String sqlStatement = this.sqlStatement(SqlMethod.INSERT_ONE);
            int size = ts.size();
            this.executeBatch((sqlSession) -> {
                AtomicInteger i = new AtomicInteger(1);
                ts.forEach((t) -> {
                    t.setId(SnowflakeIdWorker.getId());
                    t.setIsDelete(false);
                    if(companyId!=null)
                        t.setCompanyId(companyId);
                    sqlSession.insert(sqlStatement, t);
                    if (i.get() % 50 == 0 || i.get() == size) {
                        sqlSession.flushStatements();
                    }
                    i.getAndIncrement();
                });
            });
            return ts;
        }
    }

    protected Page<T> page(LambdaQueryWrapper<T> queryWrapper, final int page, final int size) {
        Page<T> pageable = new Page<>(page, size);
        IPage<T> iPage = this.getBaseMapper().selectPage(pageable, queryWrapper);
        return (Page<T>) iPage;
    }

    protected Page<T> page(LambdaQueryWrapper<T> queryWrapper, final int page, final int size, OrderItem... sortColumns) {
        Page<T> pageable = new Page<>(page, size);
        pageable.addOrder(sortColumns);
        IPage<T> iPage = this.getBaseMapper().selectPage(pageable, queryWrapper);
        return (Page<T>) iPage;
    }
}
